if (!dojo._hasResource["dojo._base.declare"]) { //_hasResource checks added by build. Do not use _hasResource directly in your code.
    dojo._hasResource["dojo._base.declare"] = true;
    dojo.provide("dojo._base.declare");
    dojo.require("dojo._base.lang");

    // this file courtesy of the TurboAjax group, licensed under a Dojo CLA

    dojo.declare =
    function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props) {
        //	summary:
        //		Create a feature-rich constructor from compact notation
        //	className:
        //		The name of the constructor (loosely, a "class")
        //		stored in the "declaredClass" property in the created prototype
        //	superclass:
        //		May be null, a Function, or an Array of Functions. If an array,
        //		the first element is used as the prototypical ancestor and
        //		any following Functions become mixin ancestors.
        //	props:
        //		An object whose properties are copied to the
        //		created prototype.
        //		Add an instance-initialization function by making it a property
        //		named "constructor".
        //	description:
        //		Create a constructor using a compact notation for inheritance and
        //		prototype extension.
        //
        //		All superclasses (including mixins) must be Functions (not simple Objects).
        //
        //		Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin
        //		ancestors are copied to the new class: changes to mixin prototypes will
        //		not affect classes to which they have been mixed in.
        //
        //		"className" is cached in "declaredClass" property of the new class.
        //
        //	example:
        //	|	dojo.declare("my.classes.bar", my.classes.foo, {
        //	|		// properties to be added to the class prototype
        //	|		someValue: 2,
        //	|		// initialization function
        //	|		constructor: function(){
        //	|			this.myComplicatedObject = new ReallyComplicatedObject();
        //	|		},
        //	|		// other functions
        //	|		someMethod: function(){
        //	|			doStuff();
        //	|		}
        //	|	);

        // process superclass argument
        // var dd=dojo.declare, mixins=null;
        var dd = arguments.callee, mixins;
        if (dojo.isArray(superclass)) {
            mixins = superclass;
            superclass = mixins.shift();
        }
        // construct intermediate classes for mixins
        if (mixins) {
            dojo.forEach(mixins, function(m) {
                if (!m) {
                    throw(className + ": mixin #" + i + " is null");
                } // It's likely a required module is not loaded
                superclass = dd._delegate(superclass, m);
            });
        }
        // prepare values
        var init = (props || 0).constructor, ctor = dd._delegate(superclass), fn;
        // name methods (experimental)
        for (var i in props) {
            if (dojo.isFunction(fn = props[i]) && !0[i]) {
                fn.nom = i;
            }
        } // 0[i] checks Object.prototype
        // decorate prototype
        dojo.extend(ctor, {declaredClass: className, _constructor: init, preamble: null}, props ||
                                                                                          0);
        // special help for IE
        ctor.prototype.constructor = ctor;
        // create named reference
        return dojo.setObject(className, ctor); // Function
    };

    dojo.mixin(dojo.declare, {
        _delegate: function(base, mixin) {
            var bp = (base || 0).prototype, mp = (mixin || 0).prototype;
            // fresh constructor, fresh prototype
            var ctor = dojo.declare._makeCtor();
            // cache ancestry
            dojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dojo.declare._extend});
            // chain prototypes
            if (base) {
                ctor.prototype = dojo._delegate(bp);
            }
            // add mixin and core
            dojo.extend(ctor, dojo.declare._core, mp || 0, {_constructor: null, preamble: null});
            // special help for IE
            ctor.prototype.constructor = ctor;
            // name this class for debugging
            ctor.prototype.declaredClass = (bp || 0).declaredClass + '_' + (mp || 0).declaredClass;
            return ctor;
        },
        _extend: function(props) {
            for (var i in props) {
                if (dojo.isFunction(fn = props[i]) && !0[i]) {
                    fn.nom = i;
                }
            }
            dojo.extend(this, props);
        },
        _makeCtor: function() {
            // we have to make a function, but don't want to close over anything
            return function() {
                this._construct(arguments);
            };
        },
        _core: {
            _construct: function(args) {
                var c = args.callee, s = c.superclass, ct = s &&
                                                            s.constructor, m = c.mixin, mct = m &&
                                                                                              m.constructor, a = args, ii, fn;
                // side-effect of = used on purpose here, lint may complain, don't try this at home
                if (a[0]) {
                    // FIXME: preambles for each mixin should be allowed
                    // FIXME:
                    //		should we allow the preamble here NOT to modify the
                    //		default args, but instead to act on each mixin
                    //		independently of the class instance being constructed
                    //		(for impedence matching)?

                    // allow any first argument w/ a "preamble" property to act as a
                    // class preamble (not exclusive of the prototype preamble)
                    if (/*dojo.isFunction*/((fn = a[0].preamble))) {
                        a = fn.apply(this, a) || a;
                    }
                }
                // prototype preamble
                if ((fn = c.prototype.preamble)) {
                    a = fn.apply(this, a) || a;
                }
                // FIXME:
                //		need to provide an optional prototype-settable
                //		"_explicitSuper" property which disables this
                // initialize superclass
                if (ct && ct.apply) {
                    ct.apply(this, a);
                }
                // initialize mixin
                if (mct && mct.apply) {
                    mct.apply(this, a);
                }
                // initialize self
                if ((ii = c.prototype._constructor)) {
                    ii.apply(this, args);
                }
                // post construction
                if (this.constructor.prototype == c.prototype && (ct = this.postscript)) {
                    ct.apply(this, args);
                }
            },
            _findMixin: function(mixin) {
                var c = this.constructor, p, m;
                while (c) {
                    p = c.superclass;
                    m = c.mixin;
                    if (m == mixin || (m instanceof mixin.constructor)) {
                        return p;
                    }
                    if (m && (m = m._findMixin(mixin))) {
                        return m;
                    }
                    c = p && p.constructor;
                }
            },
            _findMethod: function(name, method, ptype, has) {
                // consciously trading readability for bytes and speed in this low-level method
                var p = ptype, c, m, f;
                do{
                    c = p.constructor;
                    m = c.mixin;
                    // find method by name in our mixin ancestor
                    if (m && (m = this._findMethod(name, method, m, has))) {
                        return m;
                    }
                    // if we found a named method that either exactly-is or exactly-is-not 'method'
                    if ((f = p[name]) && (has == (f == method))) {
                        return p;
                    }
                    // ascend chain
                    p = c.superclass;
                } while (p);
                // if we couldn't find an ancestor in our primary chain, try a mixin chain
                return !has && (p = this._findMixin(ptype)) &&
                       this._findMethod(name, method, p, has);
            },
            inherited: function(name, args, newArgs) {
                // optionalize name argument (experimental)
                var a = arguments;
                if (!dojo.isString(a[0])) {
                    newArgs = args;
                    args = name;
                    name = args.callee.nom;
                }
                a = newArgs || args;
                var c = args.callee, p = this.constructor.prototype, fn, mp;
                // if not an instance override
                if (this[name] != c || p[name] == c) {
                    mp = this._findMethod(name, c, p, true);
                    if (!mp) {
                        throw(this.declaredClass + ': inherited method "' + name + '" mismatch');
                    }
                    p = this._findMethod(name, c, mp, false);
                }
                fn = p && p[name];
                if (!fn) {
                    throw(mp.declaredClass + ': inherited method "' + name + '" not found');
                }
                // if the function exists, invoke it in our scope
                return fn.apply(this, a);
            }
        }
    });

}
